export default {
  getStyle(obj, style) {
    //获取对象样式规则信息，IE下使用currentStyle
    return obj.currentStyle ? obj.currentStyle[style] : getComputedStyle(obj, false)[style];
  },
  //原生js动画类似jquery--animate
  animate(obj, styleJson, callback) {
    let self = this;
    clearInterval(obj.timer);
    // 开启定时器
    obj.timer = setInterval(function () {
      let flag = true;//假设所有动作都已完成成立。
      for (let styleName in styleJson) {
        //1.取当前属性值
        let iMov = 0;
        // 透明度是小数，所以得单独处理
        iMov = styleName == 'opacity' ? Math.round(parseFloat(self.getStyle(obj, styleName)) * 100) : parseInt(self.getStyle(obj, styleName));

        //2.计算速度
        let speed = 0;
        speed = (styleJson[styleName] - iMov) / 8;//缓冲处理，这边也可以是固定值
        speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);//区分透明度及小数点，向上取整，向下取整

        //3.判断是否到达预定值
        if (styleJson[styleName] != iMov) {
          flag = false;
          if (styleName == 'opacity') {//判断结果是否为透明度
            obj.style[styleName] = (iMov + speed) / 100;
            obj.style.filter = 'alpha(opacity:' + (iMov + speed) + ')';
          } else {
            obj.style[styleName] = iMov + speed + 'px';
          }
        }
      }
      if (flag) {//到达设定值，停止定时器，执行回调
        clearInterval(obj.timer);
        if (callback) {
          callback();
        }
      }
    }, 20)
  },
  /**
   * 格式化字符串
   * @param args 参数数组
   */
  formatString(args) {
    let _str = args[0];//第一个参数
    let _data = args[1];//第二个参数
    let _pdata;
    //如果第二个参数是数组或者对象类型,把第二个参数当做数据容器
    if (_data && (Array.isArray(_data) || _data.constructor === Object)) {
      _pdata = _data;
    } else { //第二个参数不是数组或者对象类型,从第二个参数开始截取数组当做数据容器
      _pdata = Array.prototype.slice.call(args, 1);
    }
    //字符串替换,正则搜索大括号中的多个数字或者字母
    return _str.replace(/{([\d|\w]+)}/g, function (match, number) {
      return typeof _pdata[number] !== 'undefined' ? _pdata[number] : match;
    });
  },
  /**
   * 创建UUID.(Universally Unique Identifier 通用唯一识别码)
   * @return {string}
   */
  uuid() {
    return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
      let r = Math.random() * 16 | 0,
          v = c === 'x' ? r : (r & 3 | 8);
      return v.toString(16);
    }).toLowerCase();
  },
  /**
   * 获取body标签内的html字符串
   * @param {string} content 待截取的字符串
   * @returns {string} 如果content不包含body标签,则返回原始字符串
   */
  getBodyHtml: function (content) {
    let _reg = /<body[^>]*>([\s\S]*)<\/body>/;
    let result = _reg.exec(content);
    if (result && result.length === 2)
      return result[1];
    return content;
  },
  /**
   * 生成随机数字(min-max之间)
   * @param {number} min 最小值
   * @param {number} max 最大值
   * @return {number}
   */
  randomNumber: function (min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  },

  /**
   * 生成随机字符串
   * @param {number} len 字符串总长度
   * @return {string}
   */
  randomString: function (len) {
    let alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let str = '';
    for (let i = 0; i < len; ++i) {
      let rand = Math.floor(Math.random() * alphabet.length);
      str += alphabet.substring(rand, rand + 1);
    }
    return str;
  },
  /**
   * 休眠执行
   * @example
   * sleep(500).then(() => {})
   */
  sleep(time) {
    return new Promise((resolve) => setTimeout(resolve, time));
  },
  /**
   * 获取固定长度的字符串
   * @param {string} str 原始字符串
   * @param {number} total 字符串总长度
   * @param {string} [defaults='0'] 默认补充字符
   */
  fixLen: function (str, total, defaults) {
    str = str.toString();
    if (typeof defaults === 'undefined') {
      defaults = '0';
    }
    let result = '';
    let times = total - (str.length);
    for (let i = 1; i <= times; i++) {
      result += defaults;
    }
    return result + str;
  },
  /**
   * 格式化为日期
   * @param {Date} date 日期
   * @param {string} format 格式
   * @example jx.formatDate(new Date('2014/07/10 10:21:12'),'MM-dd')
   */
  formatDate: function (date, format) {
    if (typeof format === 'undefined') {
      format = 'yyyy-MM-dd';
    }
    let o = {
      'M+': date.getMonth() + 1,                  //month
      'd+': date.getDate(),                       //day
      'h+': date.getHours(),                      //hour
      'm+': date.getMinutes(),                    //minute
      's+': date.getSeconds(),                    //second
      'q+': Math.floor((date.getMonth() + 3) / 3),//quarter
      'S': date.getMilliseconds() //millisecond
    };
    if (/(y+)/.test(format)) {
      format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
    }
    for (let k in o) {
      if (new RegExp('(' + k + ')').test(format)) {
        format = format.replace(RegExp.$1,
            RegExp.$1.length === 1 ? o[k] :
                ('00' + o[k]).substr(('' + o[k]).length));
      }
    }
    return format;
  },
  /**
   * 格式化为标准日期时间
   * @param {Date} date
   */
  formatDateTime: function (date) {
    return this.formatDate(date, 'yyyy-MM-dd hh:mm:ss');
  },

  /**
   * 格式化为标准时间
   * @param {Date} date
   */
  formatTime: function (date) {
    return this.formatDate(date, 'hh:mm:ss');
  },
  /**
   * 检查是否为空
   * 字符串/数字/布尔
   * 数组:没有任何元素,返回true
   * 对象:没有任何成员,返回true
   * 函数:返回false
   * @return {boolean}
   */
  isEmpty: function (obj) {
    if (!obj) return true;
    if (this.isFunc(obj)) {
      return false;
    }
    if (this.isArray(obj) || this.isObj(obj)) {
      return Object.keys(obj).length === 0;
    } else {
      return !(!!obj);
    }
  },

  /**
   * 是否是整数
   * @param {string} str 字符串
   * @return {boolean}
   */
  isInt: function (str) {
    return (new RegExp(/^\d+$/).test(str));
  },

  /**
   * 是否是数字
   * @return {boolean}
   */
  isNumber: function (obj) {
    let reg = /^[0-9]+.?[0-9]*$/;
    return reg.test(obj);
  },

  /**
   * 是否是字符串
   * @return {boolean}
   */
  isString: function (obj) {
    return typeof obj === 'string';
  },

  /**
   * 是否是布尔值
   * @return {boolean}
   */
  isBool: function (obj) {
    return typeof obj === 'boolean';
  },

  /**
   * 是否是对象类型
   * @return {boolean}
   */
  isObj: function (obj) {
    return typeof obj === 'object';
  },

  /**
   * 是否是数组类型
   * @return {boolean}
   */
  isArray: function (obj) {
    return Array.isArray(obj);
  },

  /**
   * 是否未定义
   * @param obj
   * @returns {boolean}
   */
  isUndefined: function (obj) {
    return typeof obj === 'undefined';
  },

  /**
   * 是否是函数类型
   * @return {boolean}
   */
  isFunc: function (obj) {
    return typeof obj === 'function';
  },
  /**
   * 是否包含汉字
   * @param {string} str 字符串
   * @return {boolean}
   */
  hasChinese: function (str) {
    return (new RegExp(/[\u4E00-\u9FA5]/).test(str));
  },

  /**
   * 字符串转为对象
   * @param {string|object} str 字符串
   * @return {object}
   */
  toObj: function (str) {
    if (typeof str === 'object') return str;
    if (typeof str !== 'string') return str;
    str = str && str.trim();
    if (!str) return {};
    if (str === 'null') return null;

    try {
      if (str.substring(0, 1) !== '{') {
        str = '{' + str + '}';
      }
      return (new Function('return ' + str))();
    } catch (e) {
      console.log('jx.toObject("' + str + '") 发生异常:' + e);
      return null;
    }
  },

  /**
   * 字符串转为数组
   * @param {string|Array} str 字符串
   * @return {Array}
   */
  toArray: function (str) {
    if (Array.isArray(str)) return str;
    if (typeof str !== 'string') return str;

    str = str && str.trim();
    if (!str) return [];
    if (str === 'null') return null;

    try {
      if (str.substring(0, 1) !== '[') {
        str = '[' + str + ']';
      }
      return (new Function('return ' + str))();
    } catch (e) {
      console.log('jx.toArray("' + str + '") 发生异常:' + e);
      return null;
    }
  },

  /**
   * 字符串转为函数 'function(){...}' 或 'getName' 或 'USER.getName' 均可
   * @param str 字符串
   * @return {*}
   */
  toFunc: function (str) {
    if (!str) return undefined;

    if (str.startsWith('function')) {
      return (new Function('return ' + str))();
    }

    let m_arr = str.split('.');
    let fn = window;

    for (let i = 0; i < m_arr.length; i++) {
      fn = fn[m_arr[i]];
    }
    if (typeof fn === 'function') {
      return fn;
    }

    return undefined;
  },

  /**
   * 转为数字
   * @param str
   */
  toNumber: function (str) {
    if (!str) return -1;
    return parseFloat(str);
  },

  toDecimal: function (num) {
    if (num == null) {
      num = "0"
    }
    num = num.toString().replace(/[$,]/g, "");
    if (isNaN(num)) {
      num = "0"
    }
    let sign = (num == (num = Math.abs(num)));
    num = Math.floor(num * 100 + 0.50000000001);
    let cents = num % 100;
    num = Math.floor(num / 100).toString();
    if (cents < 10) {
      cents = "0" + cents
    }
    for (let i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++) {
      num = num.substring(0, num.length - (4 * i + 3)) + "" + num.substring(num.length - (4 * i + 3))
    }
    return (((sign) ? "" : "-") + num + "." + cents)
  },

  /**
   * 转为布尔
   * @param str
   */
  toBoolean: function (str) {
    if (typeof str === 'boolean') {
      return str;
    }
    return str == 'true' || str == '1';
  },

  /**
   * 计算js表达的值
   * @param str 字符串
   */
  calcVal: function (str) {
    if (typeof str === 'object') return str;
    if (typeof str !== 'string') return str;
    str = str && str.trim();
    if (!str) return null;
    if (str === 'null') return null;

    try {
      return (new Function('return ' + str))();
    } catch (e) {
      console.log('jx.calcVal("' + str + '") 发生异常:' + e);
      return null;
    }
  }
}